//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package events_subscribe

import (
	"fmt"
	"strings"
	"time"

	"atomgit.com/openlinksaas/proto-gen-go.git/events/events_issue"
	"atomgit.com/openlinksaas/proto-gen-go.git/events_api"
	"atomgit.com/openlinksaas/proto-gen-go.git/project_issue_api"
)

func getIssueTypeStr(issueType int32) string {
	if issueType == int32(project_issue_api.ISSUE_TYPE_ISSUE_TYPE_BUG) {
		return "缺陷"
	} else if issueType == int32(project_issue_api.ISSUE_TYPE_ISSUE_TYPE_TASK) {
		return "任务"
	}
	return ""
}

func getIssueStateStr(issueState int32) string {
	if issueState == int32(project_issue_api.ISSUE_STATE_ISSUE_STATE_PLAN) {
		return "规划中"
	} else if issueState == int32(project_issue_api.ISSUE_STATE_ISSUE_STATE_PROCESS) {
		return "处理中"
	} else if issueState == int32(project_issue_api.ISSUE_STATE_ISSUE_STATE_CHECK) {
		return "检查中"
	} else if issueState == int32(project_issue_api.ISSUE_STATE_ISSUE_STATE_CLOSE) {
		return "关闭"
	}
	return ""
}

func getIssueProcessStageStr(processStage int32) string {
	if processStage == int32(project_issue_api.PROCESS_STAGE_PROCESS_STAGE_TODO) {
		return "未开始"
	} else if processStage == int32(project_issue_api.PROCESS_STAGE_PROCESS_STAGE_DOING) {
		return "执行中"
	} else if processStage == int32(project_issue_api.PROCESS_STAGE_PROCESS_STAGE_DONE) {
		return "已完成"
	}
	return ""
}

func getSubIssueStateStr(done bool) string {
	if done {
		return "完成"
	} else {
		return "未完成"
	}
}

func processIssueEvent(event *events_api.Event, cfgItemList []*CfgItem) (bool, error) {
	var err error
	var msg string

	{
		createEvent := &events_issue.CreateEvent{}
		if event.EventData.MessageIs(createEvent) {
			err = event.EventData.UnmarshalTo(createEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 创建 %s %s。", event.UserDisplayName, event.ProjectName, getIssueTypeStr(createEvent.IssueType), createEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.Create {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		updateEvent := &events_issue.UpdateEvent{}
		if event.EventData.MessageIs(updateEvent) {
			err = event.EventData.UnmarshalTo(updateEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 更新 %s %s(原标题 %s)。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(updateEvent.IssueType), updateEvent.NewTitle, updateEvent.OldTitle)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.Update {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		updateTagEvent := &events_issue.UpdateTagEvent{}
		if event.EventData.MessageIs(updateTagEvent) {
			err = event.EventData.UnmarshalTo(updateTagEvent)
			if err != nil {
				return false, err
			}
			oldTagList := []string{}
			newTagList := []string{}
			for _, tag := range updateTagEvent.OldTagList {
				oldTagList = append(oldTagList, tag.TagName)
			}
			for _, tag := range updateTagEvent.NewTagList {
				newTagList = append(newTagList, tag.TagName)
			}
			msg = fmt.Sprintf("%s 在项目 %s 更新 %s %s 标签 %s (原标签 %s)。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(updateTagEvent.IssueType), updateTagEvent.Title, strings.Join(newTagList, ","), strings.Join(oldTagList, ","))
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.UpdateTag {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		removeEvent := &events_issue.RemoveEvent{}
		if event.EventData.MessageIs(removeEvent) {
			err = event.EventData.UnmarshalTo(removeEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 把 %s %s 移入回收站。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(removeEvent.IssueType), removeEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.Remove {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		assignExecUserEvent := &events_issue.AssignExecUserEvent{}
		if event.EventData.MessageIs(assignExecUserEvent) {
			err = event.EventData.UnmarshalTo(assignExecUserEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 指派 %s 为 %s %s 执行人。", event.UserDisplayName, event.ProjectName,
				assignExecUserEvent.ExecUserDisplayName, getIssueTypeStr(assignExecUserEvent.IssueType), assignExecUserEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.AssignExecUser {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		assignCheckUserEvent := &events_issue.AssignCheckUserEvent{}
		if event.EventData.MessageIs(assignCheckUserEvent) {
			err = event.EventData.UnmarshalTo(assignCheckUserEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 指派 %s 为 %s %s 检查人。", event.UserDisplayName, event.ProjectName,
				assignCheckUserEvent.CheckUserDisplayName, getIssueTypeStr(assignCheckUserEvent.IssueType), assignCheckUserEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.AssignCheckUser {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		changeStateEvent := &events_issue.ChangeStateEvent{}
		if event.EventData.MessageIs(changeStateEvent) {
			err = event.EventData.UnmarshalTo(changeStateEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 更改 %s %s 状态为%s(原状态 %s)。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(changeStateEvent.IssueType), changeStateEvent.Title,
				getIssueStateStr(changeStateEvent.NewState), getIssueStateStr(changeStateEvent.OldState))
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.ChangeState {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		updateProcessStageEvent := &events_issue.UpdateProcessStageEvent{}
		if event.EventData.MessageIs(updateProcessStageEvent) {
			err = event.EventData.UnmarshalTo(updateProcessStageEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 更改 %s %s 执行阶段为%s(原阶段 %s)。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(updateProcessStageEvent.IssueType), updateProcessStageEvent.Title,
				getIssueProcessStageStr(updateProcessStageEvent.NewStage), getIssueProcessStageStr(updateProcessStageEvent.OldStage))
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.UpdateProcessStage {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		linkSpritEvent := &events_issue.LinkSpritEvent{}
		if event.EventData.MessageIs(linkSpritEvent) {
			err = event.EventData.UnmarshalTo(linkSpritEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 关联 %s %s 到迭代 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(linkSpritEvent.IssueType), linkSpritEvent.Title, linkSpritEvent.SpritTitle)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.LinkSprit {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		cancelLinkSpritEvent := &events_issue.CancelLinkSpritEvent{}
		if event.EventData.MessageIs(cancelLinkSpritEvent) {
			err = event.EventData.UnmarshalTo(cancelLinkSpritEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 取消关联 %s %s 到迭代 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(cancelLinkSpritEvent.IssueType), cancelLinkSpritEvent.Title, cancelLinkSpritEvent.SpritTitle)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.CancelLinkSprit {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		setStartTimeEvent := &events_issue.SetStartTimeEvent{}
		if event.EventData.MessageIs(setStartTimeEvent) {
			err = event.EventData.UnmarshalTo(setStartTimeEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 设置 %s %s 开始时间 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(setStartTimeEvent.IssueType), setStartTimeEvent.Title, time.Unix(setStartTimeEvent.StartTime/1000, 0).Format("2006-01-02"))
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.SetStartTime {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		cancelStartTimeEvent := &events_issue.CancelStartTimeEvent{}
		if event.EventData.MessageIs(cancelStartTimeEvent) {
			err = event.EventData.UnmarshalTo(cancelStartTimeEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 取消 %s %s 开始时间。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(cancelStartTimeEvent.IssueType), cancelStartTimeEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.CancelStartTime {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		setEndTimeEvent := &events_issue.SetEndTimeEvent{}
		if event.EventData.MessageIs(setEndTimeEvent) {
			err = event.EventData.UnmarshalTo(setEndTimeEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 设置 %s %s 结束时间 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(setEndTimeEvent.IssueType), setEndTimeEvent.Title, time.Unix(setEndTimeEvent.EndTime/1000, 0).Format("2006-01-02"))
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.SetEndTime {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		cancelEndTimeEvent := &events_issue.CancelEndTimeEvent{}
		if event.EventData.MessageIs(cancelEndTimeEvent) {
			err = event.EventData.UnmarshalTo(cancelEndTimeEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 取消 %s %s 结束时间。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(cancelEndTimeEvent.IssueType), cancelEndTimeEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.CancelEndTime {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		setEstimateMinutesEvent := &events_issue.SetEstimateMinutesEvent{}
		if event.EventData.MessageIs(setEstimateMinutesEvent) {
			err = event.EventData.UnmarshalTo(setEstimateMinutesEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 设置 %s %s 预估工时 %.2f小时。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(setEstimateMinutesEvent.IssueType), setEstimateMinutesEvent.Title, float32(setEstimateMinutesEvent.EstimateMinutes)/60.0)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.SetEstimateMinutes {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		cancelEstimateMinutesEvent := &events_issue.CancelEstimateMinutesEvent{}
		if event.EventData.MessageIs(cancelEstimateMinutesEvent) {
			err = event.EventData.UnmarshalTo(cancelEstimateMinutesEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 取消 %s %s 预估工时。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(cancelEstimateMinutesEvent.IssueType), cancelEstimateMinutesEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.CancelEstimateMinutes {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		setRemainMinutesEvent := &events_issue.SetRemainMinutesEvent{}
		if event.EventData.MessageIs(setRemainMinutesEvent) {
			err = event.EventData.UnmarshalTo(setRemainMinutesEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 设置 %s %s 剩余工时 %.2f小时。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(setRemainMinutesEvent.IssueType), setRemainMinutesEvent.Title, float32(setRemainMinutesEvent.RemainMinutes)/60.0)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.SetRemainMinutes {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		cancelRemainMinutesEvent := &events_issue.CancelRemainMinutesEvent{}
		if event.EventData.MessageIs(cancelRemainMinutesEvent) {
			err = event.EventData.UnmarshalTo(cancelRemainMinutesEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 取消 %s %s 剩余工时。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(cancelRemainMinutesEvent.IssueType), cancelRemainMinutesEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.CancelRemainMinutes {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		createSubIssueEvent := &events_issue.CreateSubIssueEvent{}
		if event.EventData.MessageIs(createSubIssueEvent) {
			err = event.EventData.UnmarshalTo(createSubIssueEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 为 %s %s 创建子工单 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(createSubIssueEvent.IssueType), createSubIssueEvent.IssueTitle, createSubIssueEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.CreateSubIssue {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		updateSubIssueEvent := &events_issue.UpdateSubIssueEvent{}
		if event.EventData.MessageIs(updateSubIssueEvent) {
			err = event.EventData.UnmarshalTo(updateSubIssueEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 更新 %s %s 子工单 %s(原标题 %s)。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(updateSubIssueEvent.IssueType), updateSubIssueEvent.IssueTitle,
				updateSubIssueEvent.NewTitle, updateSubIssueEvent.OldTitle)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.UpdateSubIssue {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		updateSubIssueStateEvent := &events_issue.UpdateSubIssueStateEvent{}
		if event.EventData.MessageIs(updateSubIssueStateEvent) {
			err = event.EventData.UnmarshalTo(updateSubIssueStateEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 标记  %s %s 子工单 %s 状态为 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(updateSubIssueStateEvent.IssueType), updateSubIssueStateEvent.IssueTitle,
				updateSubIssueStateEvent.Title, getSubIssueStateStr(updateSubIssueStateEvent.Done))
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.UpdateSubIssueState {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		removeSubIssueEvent := &events_issue.RemoveSubIssueEvent{}
		if event.EventData.MessageIs(removeSubIssueEvent) {
			err = event.EventData.UnmarshalTo(removeSubIssueEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 删除 %s %s 子工单 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(removeSubIssueEvent.IssueType), removeSubIssueEvent.IssueTitle, removeSubIssueEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.RemoveSubIssue {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		addDependenceEvent := &events_issue.AddDependenceEvent{}
		if event.EventData.MessageIs(addDependenceEvent) {
			err = event.EventData.UnmarshalTo(addDependenceEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 关联 %s %s 和 %s %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(addDependenceEvent.IssueType), addDependenceEvent.IssueTitle,
				getIssueTypeStr(addDependenceEvent.DependIssueType), addDependenceEvent.DependIssueTitle)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.AddDependence {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		removeDependenceEvent := &events_issue.RemoveDependenceEvent{}
		if event.EventData.MessageIs(removeDependenceEvent) {
			err = event.EventData.UnmarshalTo(removeDependenceEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 取消关联 %s %s 和 %s %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(removeDependenceEvent.IssueType), removeDependenceEvent.IssueTitle,
				getIssueTypeStr(removeDependenceEvent.DependIssueType), removeDependenceEvent.DependIssueTitle)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.RemoveDependence {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		setDeadLineTimeEvent := &events_issue.SetDeadLineTimeEvent{}
		if event.EventData.MessageIs(setDeadLineTimeEvent) {
			err = event.EventData.UnmarshalTo(setDeadLineTimeEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 设置 %s %s 底线时间 %s。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(setDeadLineTimeEvent.IssueType), setDeadLineTimeEvent.Title, time.Unix(setDeadLineTimeEvent.DeadLineTime/1000, 0).Format("2006-01-02"))
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.SetDeadLineTime {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	{
		cancelDeadLineTimeEvent := &events_issue.CancelDeadLineTimeEvent{}
		if event.EventData.MessageIs(cancelDeadLineTimeEvent) {
			err = event.EventData.UnmarshalTo(cancelDeadLineTimeEvent)
			if err != nil {
				return false, err
			}
			msg = fmt.Sprintf("%s 在项目 %s 取消 %s %s 底线时间。", event.UserDisplayName, event.ProjectName,
				getIssueTypeStr(cancelDeadLineTimeEvent.IssueType), cancelDeadLineTimeEvent.Title)
			for _, cfgItem := range cfgItemList {
				if cfgItem.eventCfg.IssueEvCfg.CancelDeadLineTime {
					sendChatMsg(msg, cfgItem.subItem)
				}
			}
			return true, nil
		}
	}

	return false, nil
}
